{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Adam with `Gluon`\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2017-10-22T11:57:59.954599Z",
     "start_time": "2017-10-22T11:57:59.262414Z"
    }
   },
   "outputs": [],
   "source": [
    "import mxnet as mx\n",
    "from mxnet import autograd\n",
    "from mxnet import gluon\n",
    "from mxnet import ndarray as nd\n",
    "import numpy as np\n",
    "import random\n",
    "\n",
    "mx.random.seed(1)\n",
    "random.seed(1)\n",
    "\n",
    "# Generate data.\n",
    "num_inputs = 2\n",
    "num_examples = 1000\n",
    "true_w = [2, -3.4]\n",
    "true_b = 4.2\n",
    "X = nd.random_normal(scale=1, shape=(num_examples, num_inputs))\n",
    "y = true_w[0] * X[:, 0] + true_w[1] * X[:, 1] + true_b\n",
    "y += .01 * nd.random_normal(scale=1, shape=y.shape)\n",
    "dataset = gluon.data.ArrayDataset(X, y)\n",
    "\n",
    "net = gluon.nn.Sequential()\n",
    "net.add(gluon.nn.Dense(1))\n",
    "square_loss = gluon.loss.L2Loss()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2017-10-22T11:58:00.179190Z",
     "start_time": "2017-10-22T11:57:59.956383Z"
    }
   },
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "import matplotlib as mpl\n",
    "mpl.rcParams['figure.dpi']= 120\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "def train(batch_size, lr, epochs, period):\n",
    "    assert period >= batch_size and period % batch_size == 0\n",
    "    net.collect_params().initialize(mx.init.Normal(sigma=1), force_reinit=True)\n",
    "    # Adam.\n",
    "    trainer = gluon.Trainer(net.collect_params(), 'adam',\n",
    "                            {'learning_rate': lr})\n",
    "    data_iter = gluon.data.DataLoader(dataset, batch_size, shuffle=True)\n",
    "    total_loss = [np.mean(square_loss(net(X), y).asnumpy())]\n",
    "    \n",
    "    for epoch in range(1, epochs + 1):\n",
    "        for batch_i, (data, label) in enumerate(data_iter):\n",
    "            with autograd.record():\n",
    "                output = net(data)\n",
    "                loss = square_loss(output, label)\n",
    "            loss.backward()\n",
    "            trainer.step(batch_size)\n",
    "\n",
    "            if batch_i * batch_size % period == 0:\n",
    "                total_loss.append(np.mean(square_loss(net(X), y).asnumpy()))\n",
    "        print(\"Batch size %d, Learning rate %f, Epoch %d, loss %.4e\" % \n",
    "              (batch_size, trainer.learning_rate, epoch, total_loss[-1]))\n",
    "\n",
    "    print('w:', np.reshape(net[0].weight.data().asnumpy(), (1, -1)), \n",
    "          'b:', net[0].bias.data().asnumpy()[0], '\\n')\n",
    "    x_axis = np.linspace(0, epochs, len(total_loss), endpoint=True)\n",
    "    plt.semilogy(x_axis, total_loss)\n",
    "    plt.xlabel('epoch')\n",
    "    plt.ylabel('loss')\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2017-10-22T11:58:01.901718Z",
     "start_time": "2017-10-22T11:58:00.180955Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Batch size 10, Learning rate 0.100000, Epoch 1, loss 6.7036e-04\n",
      "Batch size 10, Learning rate 0.100000, Epoch 2, loss 5.0751e-05\n",
      "Batch size 10, Learning rate 0.100000, Epoch 3, loss 5.0725e-05\n",
      "w: [[ 1.9997046  -3.39914703]] b: 4.1986 \n",
      "\n"
     ]
    },
    {
     "data": {
      "image/png": "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\ns2LTXxxz6pQRnHf0ON48/QDG9uCeT0nqLUNlCbOlUtKevLKlmd8+u5qfPbacp3bRJX/8QcM48aDh\nHDNxGMdMGMpBIxqosJtcUpH0NlQ6+luSMjJ6cC3vO2US7ztlEs+t3szPHl3Ob+auYtWmJgCeXLqR\nJ5e+GjbrqiuYPHIQU0YPYsqoRqaMHsTBowYxZXQjQ+urs/o2+sTmplZWbWxi5aYdrNyY25au38GW\nplaqKiqorgwqK4LqygpqqyporK1icF1uJP7owbWMaqyloaaShppK6qor84+rqKuuKEqrtPq/jo5E\nW0eipqrwsy+2tnewZN02Vm9qZsP2FgCqK4OqigpqqytoqKliUG0lg2qq+tXvqi2VRWRLpaSeSinx\n1PJN/GbuKh5cuJYFq7fQ2r73v6dHNdYwYVg9Dfl/hOpqKneer70j0ZFe+3hXKiI3Wj0iqAgIcv+A\nVVbkAltVRVCR/1q582sFVZVBdWUu0NVUVVCT/1pdWdFlX7xmX8rX05GgIyXaOjpYv62VdVubWZcf\nbb92awurNu5g1aYmtja3Fewz7q6+unvY7B48c48b66p23kc7vKGGmqoKqvLff0dHoqW9g9b2RGtb\nB63tHbS0d9DSlt/X+bijg/b2RGtHoi2/r/O4lrYOmts7aG5tJyKYMKw+tw2vZ8Sg3DWHD6qmMoId\nre3saGnf+bW5rfNaHbTu5gdcEVAZuZ9h520fbR25+tryj9vaE1X5cFPd5WdWVZF7nPusqqivyQWc\nzp9jIvdzzD3PPe7ovEZ7B20duc+gres1u117V8e25mtKKVd/RUXut3Ln72g+Y6UEiVcHzCXyO+jc\nn3vSkaC5rZ2m1g6aWnOfW+fX5tbc/q3NbWxuamVrcxsp5X4/xg6pZeKIBg7Kb5NGNjB6cB2Ntbk/\nb/U1lbnvuQPaU2JLUysbtrWycXsLG7a3smF7biaJlzc38cKaLby0dts+/bnuKgIG1VTxxD+dU5Sg\nC7ZUSlJZiQiOmziM4yYOA6CptZ0Fq7fwzIpNLHplKy++so2X1m5j+YbtrwmHa7e2sHZrS0ZV972K\ngAnD6xneUPOaQNTWkWhqbWdrcxvbW9r36Vw7WnPhTNqVHa3tLF63ncXrtmdaR8oH4mIFykIwVBaB\nk59LKpS66kqOnTiMY/Mhs1NTazvL1m9nUT5kvvjKVlZvbmJHSzvbW9ppamsngIqI3FaRa9mpyLfw\n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\ns+GYHgvcRbrx8wPSvRF3AV+vqzcgYtRnKs3MzMysMs+pNDMzM7PKnFSamZmZWWVOKs3MzMysMieV\nZmZmZlaZk0ozMzMzq8xJpZmZmZlV5qTSzMzMzCpzUmlmZmZmlTmpNDMzM7PKnFSamXUhSedLCkkj\n290XMxscnFSamZmZWWVOKs3MzMysMieVZmZmZlaZk0ozsxaStK2k6yQtkfSepGcknVh4/qA8t/EY\nSVMlvS7pHUm3S9quZH+TJf1D0ruS3pA0XdK2JfXGSpohaWmu+5ykC0q6uKmkaZKWSVou6XpJG/fz\nMJhZF/h4uztgZjZYSRoN/B0I4ApgKXAYcK2k4RFxWaH6ubneRcCWwFnA3ZLGRcS7eX8nANcDjwA/\nAUYDZwL7S9ozIpblensADwAfAFcDi4GdgK/l1ymaAbyY9zce+A7wL2BKf42DmXUHJ5VmZq1zATAE\n+FxEvJnLrpL0R+B8Sb8r1N0c2C0iVgJImk9K+L4L/EbSBqSE82ngwIhYnevNBf4CnA38NO/rckDA\n+Ih4ufYCks4p6eNjEXFSoc4WwEk4qTSzdeTL32ZmLSBJwFHArPxwZG0D7gRGkM4M1txYSyizmcBr\nwOH58QTSGcwrawklQETMBhYAX82vOwo4ELiumFDmulHS1avqHj8AbCFp+Locr5mZz1SambXGKGBT\n4OS8ldkSeDv/vrD4RESEpEXAmFy0Q/75XMl+FgAH5N93zD+f7mM/X657XOvPZsCKPu7DzMxJpZlZ\ni9SuBE0HbmhQ50ngs+unOw2taVCu9doLMxvwnFSambXGUmAlMCQi7m5USVItqdylrlzAzqTEE+Cl\n/HNX4G91u9m18PwL+efuzXXbzKw5nlNpZtYCEbEGuAU4StJaCV6e+1h0vKRhhceTgK2BO/LjR0l3\nZZ8qaaPCfg4DdgNm59ddCtwPnChp+7rX9NlHM2sZn6k0M2udc4CDgYclXQM8S7rLezxwaP695i1g\nrqTrSUsFnQUsAq4BiIgPJE0hLSl0X76DvLak0GLg0sK+vg/MBeZLupq0ZNAY0s0841pxoGZmTirN\nzFokIpZI2hs4DzgSOB14E3iGtZfsmQrsQVovchhwD3B6RKwq7G+apFWkZPUi4B3gNmBKbY3KXO8J\nSfsCPwNOA4aSLo/PaMVxmpkBqHyFCTMzWx8kHQTcC0yOiJlt7o6ZWdM8p9LMzMzMKnNSaWZmZmaV\nOak0MzMzs8o8p9LMzMzMKvOZSjMzMzOrzEmlmZmZmVXmpNLMzMzMKnNSaWZmZmaVOak0MzMzs8qc\nVJqZmZlZZU4qzczMzKwyJ5VmZmZmVpmTSjMzMzOrzEmlmZmZmVXmpNLMzMzMKvsfyC4FLzW3D50A\nAAAASUVORK5CYII=\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x1067596a0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "train(batch_size=10, lr=0.1, epochs=3, period=10)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Next\n",
    "[Fast & flexible: combining imperative & symbolic nets with HybridBlocks](../chapter07_distributed-learning/hybridize.ipynb)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For whinges or inquiries, [open an issue on  GitHub.](https://github.com/zackchase/mxnet-the-straight-dope)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
